package development;

import state.DrawListener;
import state.GameConstants;
import state.GameForm;
import state.GameGlobal;
import state.GameImage;
import state.Graphics;
import state.Key;
import state.Sprite;
import state.component.Event;
import state.component.EventListener;
import state.component.GameMenu;
import state.component.GridMenu;
import state.component.TextField;
import state.font.FontManager;
import state.font.ImageText;
import state.util.GameColor;
import state.util.Hashtable;
import state.util.ImageUtil;
import state.util.NumberUtil;
import development.bean.Table;
import development.group.FrmGroupFriendAndTop;
import development.group.FrmGroupListTableFreeUserChat;
import development.group.FrmGroupNapXuAndExchangeGold;
import development.socket.SocketClientUtil;

public class FrmListTable extends GameForm implements EventListener, DrawListener {
  private final int MONEY_CHAR_DISTANCE = 0;
  private final int TABLE_HOZ_DISTANCE = 62;
  private final int TABLE_VER_DISTANCE = 70;
  private final int TABLE_DX = 33;
  private final int TABLE_DY = 35;
  private final int TABLE_AND_CHAIR_DISTANCE = 22;

  private int NUMBER_OF_TABLE_PER_ROW = 4;

  private GameImage tableImage;
  private GameImage[] chairImages;
  private GameImage lockImage;
  private GameImage[] personImages;
  private GameImage moneyImage;
  private GameImage[] numberImages;
  private GameImage popupImage;

  private ImageText text8;
  private TextField passwordTextField;
  private GridMenu gridMenu;
  private Sprite inputPasswordSprite;

  private boolean isShowInputPasswordBox;
  private boolean isLockKey;
  private GameMenu menu;
  private int titleMoveCount;
  private int count;

  private static GameForm singleton;

  public static GameForm instance() {
    if (singleton == null) {
      singleton = new FrmListTable();
    }
    return singleton;
  }

  public void init(Hashtable parameters) {
    if (Global.currentRoom.getMaxUserPerTable() == 6) {
      tableImage = ImageUtil.getImage(Constants.TABLE_6_PLAYER_IMAGE_CATEGORY, "table6.png");
      personImages = new GameImage[6];
      for (int i = 0; i < 6; i++) {
        personImages[i] = ImageUtil.getImage(Constants.TABLE_6_PLAYER_IMAGE_CATEGORY, "nguoi" + (i + 1) + ".png");
      }
      chairImages = new GameImage[6];
      for (int i = 0; i < 6; i++) {
        chairImages[i] = ImageUtil.getImage(Constants.TABLE_6_PLAYER_IMAGE_CATEGORY, "chair" + (i + 1) + ".png");
      }
    } else if (Global.currentRoom.getMaxUserPerTable() == 5) {
      tableImage = ImageUtil.getImage(Constants.TABLE_5_PLAYER_IMAGE_CATEGORY, "table5.png");
      personImages = new GameImage[5];
      for (int i = 0; i < 5; i++) {
        personImages[i] = ImageUtil.getImage(Constants.TABLE_5_PLAYER_IMAGE_CATEGORY, "nguoi" + (i + 1) + ".png");
      }
      chairImages = new GameImage[5];
      for (int i = 0; i < 5; i++) {
        chairImages[i] = ImageUtil.getImage(Constants.TABLE_5_PLAYER_IMAGE_CATEGORY, "chair" + (i + 1) + ".png");
      }
    } else {
      tableImage = ImageUtil.getImage(Constants.MANDATORY_CATEGORY, "Table.png");
      personImages = new GameImage[4];
      personImages[0] = ImageUtil.getImage(Constants.MANDATORY_CATEGORY, "Nguoi.png");
      personImages[1] = ImageUtil.rotate(personImages[0], 90);
      personImages[2] = ImageUtil.rotate(personImages[0], 180);
      personImages[3] = ImageUtil.rotate(personImages[0], 270);

      chairImages = new GameImage[4];
      chairImages[0] = ImageUtil.getImage(Constants.MANDATORY_CATEGORY, "icon_chair.png");
      chairImages[1] = ImageUtil.rotate(chairImages[0], 90);
      chairImages[2] = ImageUtil.rotate(chairImages[0], 180);
      chairImages[3] = ImageUtil.rotate(chairImages[0], 270);
    }

    lockImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "Lock.png");
    popupImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "bg_popup.png");
    GameImage numberImage = ImageUtil.getImage(Constants.MANDATORY_CATEGORY, "number_yellow.png");

    numberImages = new GameImage[10];
    for (int i = 0; i < 10; i++) {
      numberImages[i] = ImageUtil.getSubImage(numberImage, 0, i * 8, 5, 8, true);
    }
    moneyImage = ImageUtil.getSubImage(numberImage, 0, 103, 5, 9, true);
    numberImage = null;

    isLockKey = false;
    titleMoveCount = 0;
    count = 0;

    text8 = FontManager.getFont(FontManager.FONT_SIZE_8);
    isShowInputPasswordBox = false;
    if (GameConstants.IS_240x320_SCREEN) {
      NUMBER_OF_TABLE_PER_ROW = 4;
    } else {
      NUMBER_OF_TABLE_PER_ROW = 5;
    }
    menu = new GameMenu(null, new String[] { "Update danh sách", "Tự động tìm bàn", "Mời chơi", "Bạn bè", "Nạp xu", "Đổi gold", "Thông tin TK" }, 7, this, Constants.MENU_STYLE, 0, GameConstants.SCREEN_HEIGHT - 45);

    FrmGroupListTableFreeUserChat frmGroupListTableFreeUserChat = (FrmGroupListTableFreeUserChat) FrmGroupListTableFreeUserChat.instance();
    gridMenu = new GridMenu(_manager, null, null, NUMBER_OF_TABLE_PER_ROW, TABLE_DX, TABLE_DY, TABLE_HOZ_DISTANCE, TABLE_VER_DISTANCE, this);
    gridMenu.setNextTabWhenEndRow(frmGroupListTableFreeUserChat.getMultiTab());

    inputPasswordSprite = new Sprite(null, _manager, 0, 0, Constants.TOP_LEFT_ANCHOR);
    inputPasswordSprite.setSize(Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT);
    inputPasswordSprite.setVisible(false);
    inputPasswordSprite.setDrawListener(new DrawListener() {
      public void paint(Sprite source, Graphics g) {
        if (isShowInputPasswordBox) {
          g.drawImage(popupImage, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2, GameConstants.CENTER_ANCHOR);
          text8.drawString2(g, "Nhập mật khẩu của phòng", GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 - 40, GameConstants.TOP_HCENTER_ANCHOR);
          passwordTextField.setVisible(true);
          DrawUtils.getBottomBar(_manager).setLeftMenu("", null);
          DrawUtils.setBottomBar(_manager, "Đồng ý", "Sửa", "Hủy");
          _manager.disableTouchPad();
          return;
        }
      }
    });

    passwordTextField = new TextField(_manager, TextField.CONSTRAINT_PASSWORD, Constants.TEXT_FIELD_STYLE);
    passwordTextField.setSize(100, 20);
    passwordTextField.setPosition(GameConstants.SCREEN_WIDTH / 2 - 50, GameConstants.SCREEN_HEIGHT / 2 - 10);
    passwordTextField.setFocused(true);
    updateTableList();
    SocketClientUtil.getTableList(Global.currentRoom.getId());
  }

  public void updateTableList() {
    if (gridMenu == null) {
      return;
    }

    gridMenu.clearData();
    for (int i = 0; i < Global.currentRoom.numberOfChilds(); i++) {
      Sprite sprite = new Sprite(null, null, 0, 0, Constants.TOP_LEFT_ANCHOR);
      sprite.setSize(TABLE_HOZ_DISTANCE, TABLE_VER_DISTANCE);
      sprite.setId((byte) i);
      gridMenu.addSpriteItem(sprite, null);
      sprite.setDrawListener(this);
    }
  }

  public void paint(state.Sprite source, Graphics g) {
    // Draw table
    int i = source.getId();
    Table table = null;
    if (i <= Global.currentRoom.numberOfChilds() - 1) {
      table = (Table) Global.currentRoom.getChild(i);
    }
    if(table == null){
      return;
    }
    int x1 = source.getRealX();
    int y1 = 36 + source.getRealY();

    g.drawImage(tableImage, x1, y1, GameConstants.CENTER_ANCHOR);
    if (table.isLocked()) {
      g.drawImage(lockImage, x1 + 16, y1 - 16, GameConstants.CENTER_ANCHOR);
    }
    drawMoneyByCenterAnchor(g, table.getBid(), x1, y1 + 33);
    text8.drawString2(g, table.getName().substring(table.getName().length() - 2), GameColor.WHITE_CODE, x1, y1, GameConstants.CENTER_ANCHOR);

    if (table.getMaxUser() <= 4) {
      drawNormalTable(g, table, x1, y1);
    } else if (table.getMaxUser() == 5) {
      draw5PlayerTable(g, table, x1, y1);
    } else if (table.getMaxUser() == 6) {
      draw6PlayerTable(g, table, x1, y1);
    }

    // Draw border for choose table
    if (i == gridMenu.getCurrentSelectedIndex()) {
      g.setColor(GameColor.WHITE_CODE);
      int width1 = TABLE_AND_CHAIR_DISTANCE + 5;
      g.drawRect(x1 - width1, y1 - width1, 2 * width1, 2 * width1);
    }
  }

  public void draw(Graphics g) {
    DrawUtils.drawBackground(g);
    String levelText = "SƠ CẤP";
    if (Global.currentRoom.getType() == 1) {
      levelText = "TRUNG CẤP";
    } else if (Global.currentRoom.getType() == 2) {
      levelText = "VIP";
    }

    // Draw title in the tab
    String title = Global.currentGame.getName() + " - " + levelText + " - Phòng " + Global.currentRoom.getName();
    count++;
    if (count % 10 == 0) {
      titleMoveCount++;
      titleMoveCount = titleMoveCount % (title.length() - 1);
    }
    FrmGroupListTableFreeUserChat frmGroupListTableFreeUserChat = (FrmGroupListTableFreeUserChat) FrmGroupListTableFreeUserChat.instance();
    frmGroupListTableFreeUserChat.getMultiTab().setTitle(0, title.substring(titleMoveCount));

    if (isShowInputPasswordBox) {
      inputPasswordSprite.setVisible(true);
      return;
    }
    inputPasswordSprite.setVisible(false);
    passwordTextField.setVisible(false);
    DrawUtils.getBottomBar(_manager).setLabels("Menu", "Chọn", "Trở về");
    DrawUtils.getBottomBar(_manager).setLeftMenu("Menu", menu);
  }

  private void draw5PlayerTable(Graphics g, Table table, int x1, int y1) {
    g.drawImage(chairImages[0], x1, y1 + 23, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[1], x1 - 12, y1 - 15, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[2], x1 + 12, y1 - 15, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[3], x1 - 20, y1 + 8, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[4], x1 + 20, y1 + 8, GameConstants.CENTER_ANCHOR);

    // Draw player
    for (int j = 0; j < table.getConcurrentUser(); j++) {
      switch (j) {
      case 0:
        g.drawImage(personImages[0], x1, y1 + 19, GameConstants.CENTER_ANCHOR);
        break;
      case 1:
        g.drawImage(personImages[1], x1 - 11, y1 - 14, GameConstants.CENTER_ANCHOR);
        break;
      case 2:
        g.drawImage(personImages[2], x1 + 11, y1 - 14, GameConstants.CENTER_ANCHOR);
        break;
      case 3:
        g.drawImage(personImages[3], x1 - 18, y1 + 6, GameConstants.CENTER_ANCHOR);
        break;
      case 4:
        g.drawImage(personImages[4], x1 + 18, y1 + 6, GameConstants.CENTER_ANCHOR);
        break;
      }
    }
  }

  private void draw6PlayerTable(Graphics g, Table table, int x1, int y1) {
    g.drawImage(chairImages[0], x1, y1 + 23, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[1], x1, y1 - 23, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[2], x1 - 19, y1 - 13, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[3], x1 + 18, y1 + 11, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[4], x1 - 18, y1 + 11, GameConstants.CENTER_ANCHOR);
    g.drawImage(chairImages[5], x1 + 18, y1 - 11, GameConstants.CENTER_ANCHOR);

    // Draw player
    for (int j = 0; j < table.getConcurrentUser(); j++) {
      switch (j) {
      case 0:
        g.drawImage(personImages[0], x1, y1 + 19, GameConstants.CENTER_ANCHOR);
        break;
      case 1:
        g.drawImage(personImages[1], x1, y1 - 19, GameConstants.CENTER_ANCHOR);
        break;
      case 2:
        g.drawImage(personImages[2], x1 - 18, y1 - 12, GameConstants.CENTER_ANCHOR);
        break;
      case 3:
        g.drawImage(personImages[3], x1 + 17, y1 + 10, GameConstants.CENTER_ANCHOR);
        break;
      case 4:
        g.drawImage(personImages[4], x1 - 17, y1 + 10, GameConstants.CENTER_ANCHOR);
        break;
      case 5:
        g.drawImage(personImages[5], x1 + 17, y1 - 10, GameConstants.CENTER_ANCHOR);
        break;
      }
    }
  }

  private void drawNormalTable(Graphics g, Table table, int x1, int y1) {
    // Draw chairs image
    switch (table.getMaxUser()) {
    case 2:
      g.drawImage(chairImages[0], x1 - TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_LEFT_ANCHOR);
      g.drawImage(chairImages[2], x1 + TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_RIGHT_ANCHOR);
      break;
    case 3:
      g.drawImage(chairImages[0], x1 - TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_LEFT_ANCHOR);
      g.drawImage(chairImages[1], x1, y1 - TABLE_AND_CHAIR_DISTANCE, GameConstants.TOP_HCENTER_ANCHOR);
      g.drawImage(chairImages[2], x1 + TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_RIGHT_ANCHOR);
      break;
    case 4:
      g.drawImage(chairImages[0], x1 - TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_LEFT_ANCHOR);
      g.drawImage(chairImages[1], x1, y1 - TABLE_AND_CHAIR_DISTANCE, GameConstants.TOP_HCENTER_ANCHOR);
      g.drawImage(chairImages[2], x1 + TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_RIGHT_ANCHOR);
      g.drawImage(chairImages[3], x1, y1 + TABLE_AND_CHAIR_DISTANCE, GameConstants.BOTTOM_HCENTER_ANCHOR);
      break;
    }

    // Draw player
    for (int j = 0; j < table.getConcurrentUser(); j++) {
      switch (j) {
      case 0:
        g.drawImage(personImages[0], x1 - TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_LEFT_ANCHOR);
        break;
      case 1:
        g.drawImage(personImages[2], x1 + TABLE_AND_CHAIR_DISTANCE, y1, GameConstants.VCENTER_RIGHT_ANCHOR);
        break;
      case 2:
        g.drawImage(personImages[1], x1, y1 - TABLE_AND_CHAIR_DISTANCE, GameConstants.TOP_HCENTER_ANCHOR);
        break;
      case 3:
        g.drawImage(personImages[3], x1, y1 + TABLE_AND_CHAIR_DISTANCE, GameConstants.BOTTOM_HCENTER_ANCHOR);
        break;
      }
    }
  }

  private void drawMoneyByCenterAnchor(Graphics g, int money, int x, int y) {
    String moneyStr = String.valueOf(money);
    GameImage[] images = new GameImage[moneyStr.length() + 1];
    int totalWidth = 0;
    for (int i = 0; i < moneyStr.length(); i++) {
      images[i] = numberImages[NumberUtil.parseInt(String.valueOf(moneyStr.charAt(i)))];
      totalWidth += images[i].getWidth() + MONEY_CHAR_DISTANCE;
    }
    images[moneyStr.length()] = moneyImage;
    totalWidth += images[moneyStr.length()].getWidth() + MONEY_CHAR_DISTANCE;
    x -= totalWidth / 2;

    for (int i = 0; i < moneyStr.length(); i++) {
      g.drawImage(images[i], x, y, GameConstants.VCENTER_LEFT_ANCHOR);
      x += images[i].getWidth() + MONEY_CHAR_DISTANCE;
    }
  }

  public void keyReleased(int keyCode) {
    if (isShowInputPasswordBox) {
      switch (keyCode) {
      case Key.SOFT_LEFT:
        SocketClientUtil.joinTableRequest(Global.currentTable.getId(), passwordTextField.getText());
        break;
      case Key.FIRE:
        passwordTextField.pointerReleased(passwordTextField, passwordTextField.getRealX(), passwordTextField.getRealY());
        break;
      case Key.SOFT_RIGHT:
        isShowInputPasswordBox = false;
        passwordTextField.setText("");
        break;
      default:
        passwordTextField.keyReleased(null, keyCode);
        break;
      }
      return;
    }

    if (isLockKey) {
      return;
    }

    switch (keyCode) {
    case Key.FIRE:
      if (Global.currentRoom.numberOfChilds() == 0) {
        return;
      }
      chooseTable(gridMenu.getCurrentSelectedIndex());
      break;
    case Key.SOFT_RIGHT:
      SocketClientUtil.leaveRoomRequest();
      GameGlobal.nextState(FrmListRoom.instance(), null);
      break;
    }
  }

  private void chooseTable(int currentTableIndex) {
    Global.currentTable = (Table) Global.currentRoom.getChild(currentTableIndex);
    if (Global.currentTable.isLocked()) {
      isShowInputPasswordBox = true;
      return;
    }
    SocketClientUtil.joinTableRequest(Global.currentTable.getId(), null);
  }

  public void alertEventPerform(int alertType, int eventType, int alertId) {
    // Khi người chơi nạp điểm
    if (alertId == 99) {
      if (eventType == 0) {
        FrmGroupNapXuAndExchangeGold.backForm = FrmGroupListTableFreeUserChat.instance();
        Global.nextState(FrmGroupNapXuAndExchangeGold.instance(), null);
        FrmGroupNapXuAndExchangeGold.setTab(1);
      } else if (eventType == 1) {
        FrmGroupNapXuAndExchangeGold.backForm = FrmGroupListTableFreeUserChat.instance();
        Global.nextState(FrmGroupNapXuAndExchangeGold.instance(), null);
      }
    }
  }

  public void onActionPerform(Event event) {
    if (event.getSource() == gridMenu) {
      chooseTable(gridMenu.getCurrentSelectedIndex());
      return;
    }

    // "Cập nhật danh sách", "Tự động tìm bàn", "Mời người chơi", "Bạn bè", "Nạp xu", "Đổi gold", "Thông tin TK"
    String action = event.getAction();
    if (action.equals("Update danh sách")) { // Cập nhật danh sách
      SocketClientUtil.getTableList(Global.currentRoom.getId());
    } else if (action.equals("Tự động tìm bàn")) { // Tự động tim bàn
      SocketClientUtil.autoFindTable();
    } else if (action.equals("Mời chơi")) {
      FrmGroupListTableFreeUserChat.setTab(1);
    } else if (action.equals("Bạn bè")) {
      GameGlobal.nextState(FrmGroupFriendAndTop.instance(), null);
      FrmGroupFriendAndTop.backForm = FrmGroupListTableFreeUserChat.instance();
    } else if (action.equals("Nạp xu")) {
      FrmGroupNapXuAndExchangeGold.backForm = FrmGroupListTableFreeUserChat.instance();
      Global.nextState(FrmGroupNapXuAndExchangeGold.instance(), null);
    } else if (action.equals("Đổi gold")) {
      FrmGroupNapXuAndExchangeGold.backForm = FrmGroupListTableFreeUserChat.instance();
      Global.nextState(FrmGroupNapXuAndExchangeGold.instance(), null);
      FrmGroupNapXuAndExchangeGold.setTab(1);
    } else if (action.equals("Thông tin TK")) {
      FrmUserInfo.goBackForm = FrmGroupListTableFreeUserChat.instance();
      Global.nextState(FrmUserInfo.instance(), null);
    }
  }

  public void destroy() {
    tableImage = null;
    lockImage = null;
    personImages = null;
    chairImages = null;
    moneyImage = null;
    numberImages = null;
    popupImage = null;
    text8 = null;
    gridMenu = null;
    passwordTextField = null;
    inputPasswordSprite = null;
    menu = null;
  }
}
